﻿#include "../../hmi.h"

#ifdef WIN32
#include <Windows.h>
#pragma comment(lib, "ws2_32")
static ret_t socket_init() {
  int iResult;
  WSADATA wsaData;
  iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  if (iResult != 0) {
    log_debug("WSAStartup failed: %d\n", iResult);
    return RET_FAIL;
  }

  return RET_OK;
}

static ret_t socket_deinit() {
  WSACleanup();
  return RET_OK;
}
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
#define socket_init()
#define socket_deinit()
#endif/*WIN32*/

#define SA struct sockaddr

static ret_t socket_wait_for_data(int sock, uint32_t timeout_ms) {
  fd_set fdsr;
  int ret = 0;
  struct timeval tv = {0, 0};

  FD_ZERO(&fdsr);
  FD_SET(sock, &fdsr);

  tv.tv_sec = timeout_ms / 1000;
  tv.tv_usec = (timeout_ms % 1000) * 1000;

  FD_SET(sock, &fdsr);
  ret = select(sock + 1, &fdsr, NULL, NULL, &tv);

  return ret > 0 && FD_ISSET(sock, &fdsr) ? RET_OK : RET_TIMEOUT;
}

static int connect_to(const char* ip, int port) {
  int sockfd = 0;
  struct sockaddr_in servaddr;

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd == -1) {
    log_debug("socket creation failed...\n");
    exit(EXIT_FAILURE);
  }
  memset(&servaddr, 0x00, sizeof(servaddr));

  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = inet_addr(ip);
  servaddr.sin_port = htons(port);

  if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
    log_debug("connection with the server failed...\n");
    exit(EXIT_FAILURE);
  }

  return sockfd;
}

static int32_t hmi_on_read(hmi_t* hmi, void* data, uint32_t size) {
  return recv(hmi->fd, data, size, 0);
}

static int32_t hmi_on_write(hmi_t* hmi, const void* data, uint32_t size) {
  return send(hmi->fd, data, size, 0);
}

static int32_t s_temp = 0;
#define STR_PROP_TEMP "空调_温度"
#define STR_PROP_MODE "空调_模式"

static ret_t hmi_on_prop_changed(hmi_t* hmi, const char* name, const value_t* v) {
  log_debug("hmi_on_prop_changed: %s=%d\n", name, value_int32(v));
  if (strcmp(STR_PROP_TEMP, name) == 0) {
    s_temp = value_int32(v);
  }
  return RET_OK;
}

int main(int argc, char* argv[]) {
  hmi_t hmi;
  int fd = 0;
  int32_t mode = 0;

  socket_init();
  fd = connect_to("127.0.0.1", 2233);
  return_value_if_fail(fd > 0, EXIT_FAILURE);

  /*初始化*/
  hmi_init_with_fd(&hmi, hmi_on_read, hmi_on_write, hmi_on_prop_changed, fd);

  while (TRUE) {
    /*设置数据*/
    hmi_set_prop_int(&hmi, STR_PROP_TEMP, s_temp++);

    /*获取数据*/
    mode = hmi_get_prop_int(&hmi, STR_PROP_MODE, 0);
    if (s_temp > 60) {
      s_temp = 0;
    }

    log_debug("%s=%d %s=%d\n", STR_PROP_TEMP, s_temp, STR_PROP_MODE, mode);

    /*分发事件*/
    if (socket_wait_for_data(hmi.fd, 1000) == RET_OK) {
      hmi_dispatch(&hmi);
    }
  }

  /*释放资源*/
  hmi_deinit(&hmi);
  close(fd);
	socket_deinit();

  return EXIT_SUCCESS;
}
